#!/bin/bash

shopt -s nullglob

. $LKP_SRC/lib/install.sh
. $LKP_SRC/distro/common
. $LKP_SRC/distro/package-manager/dnf
. $LKP_SRC/lib/debug.sh

distro_install_depends()
{
	local script
	local bm="$1"
	local scripts=$(find $LKP_SRC/distro/depends/ -name "$bm" -o -name "${bm}.[0-9]")

	for script in $scripts
	do
		script=$(basename $script)
		packages=$(get_dependency_packages $DISTRO $script)

		[ -z "$packages" ] && continue

		echo install packages for $script: $packages

		$LKP_SRC/distro/installer clear $packages
	done
}

pack_benchmark()
{
	distro_install_depends lkp-dev

	for BM_NAME in $benchmark
	do
		distro_install_depends $BM_NAME-dev || continue
		echo $LKP_SRC/sbin/pack -d $DISTRO -f -c -s $PKG_MNT/$pack_to $BM_NAME
		(
			setup_proxy
			$LKP_SRC/sbin/pack -d $DISTRO -f -c -s $PKG_MNT/$pack_to $BM_NAME
		)
	done
}

install_runtime_depends()
{
	local scripts=
	local job=$1

	parse_yaml $job
	distro_install_depends lkp

	for script in $scripts
	do
		distro_install_depends $script
	done
}

fixup_preinstall()
{
	:
}

resolve_uninstalled_bundles()
{
	for b in $1
	do
		[ "$b" = "os-core" ] && continue
		[ -f $tmpdir/Manifest.$b ] && continue
		cp -a $(ls -t /var/lib/swupd/*/Manifest.$b | head -1) $tmpdir/

		uninstalled_atomic_bundles="$uninstalled_atomic_bundles $b"

		# some bundles include other bundles
		include_bundles=$(cat $tmpdir/Manifest.$b | grep ^includes: | awk -F'^includes:' '{print $2}')
		resolve_uninstalled_bundles "$include_bundles"
	done
}

# delta = to_pack - installed
delta_bundles()
{
	local installed_bundles=$1
	local to_pack=$2
	local delta=

	for i in $to_pack
	do
		grep -qw "^$i$" $installed_bundles || delta="$delta $i"
	done

	echo $delta
}

# if /usr/share/clear/bundles/xxx is removed,
# swupd bundle-list cannot detect this bundle
fixup_benchmark()
{
	[ "$BM_NAME" = "pack-deps" ] || return
	for d in $delta
	do
		rm -rf /usr/share/clear/bundles/$d
	done
}

list_bundles_files()
{
	local delta=$(delta_bundles $installed_bundles_file "$uninstalled_atomic_bundles")

	echo "Actually pack bundles: $delta"
	echo "$delta" >$pack_to/.${BM_NAME}.bundles

	fixup_benchmark

	for d in $delta
	do
		while read a b c f
		do
			[ -n "$f" ] && [ -e "$f" ] && echo "$f" >>$tmpdir/$d.list
		done <$tmpdir/Manifest.$d
	done
}

pack_bundles_files()
{
	local date=$(date +"%Y%m%d")
	# allow empty
	ls $tmpdir | grep -q "\.list$" >/dev/null || {
		echo "empty PACKAGE_LIST for $BM_NAME"
		return 0
	}

	cat $tmpdir/*.list | sort | uniq |
		cpio --quiet -o -H newc --owner=root.root |
		gzip -n -9 >$pack_to/${BM_NAME}_$date.cgz || return

	ln -sf ${BM_NAME}_$date.cgz $pack_to/${BM_NAME}.cgz || return
	chown .lkp $pack_to/${BM_NAME}_$date.cgz $pack_to/${BM_NAME}.cgz || return

	echo package uploaded to $pack_to/${benchmark}.cgz
}

# 1. install all un-installed bundles and record it to uninstalled_bundles
# 2. list atomic bundles by searching uninstalled_bundles recursively
# 3. list files for each atomic bundle and pack it
pack_benchmark_deps()
{
	local installed_bundles_file=$(mktemp /tmp/pack-deps-installed-bundles-XXXXXXXX)
	local uninstalled_bundles=
	local uninstalled_atomic_bundles=

	swupd bundle-list >$installed_bundles_file

	for BM_NAME in $benchmark
	do
		local tmpdir=$(mktemp -d /tmp/pack-deps-$BM_NAME-XXXXXXXX)

		check_shared_package $BM_NAME
		packages=$(echo $(get_dependency_packages $DISTRO $BM_NAME))
		for p in $packages
		do
			swupd bundle-list | grep -qw "^$p$" && continue
			swupd bundle-list -a | grep -qw "^$p$" || return
			$LKP_SRC/distro/installer clear $p 2>&1 | grep -v "Out of memory"

			uninstalled_bundles="$uninstalled_bundles $p"
		done

		echo "uninstalled bundles: $uninstalled_bundles"
		resolve_uninstalled_bundles "$uninstalled_bundles"

		echo "uninstalled_atomic_bundles: $uninstalled_atomic_bundles"
		list_bundles_files

		pack_bundles_files || return
	done
}
